package com.seqb.manage.dict.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.seqb.common.ResultVo;
import com.seqb.common.config.RedisConfig;
import com.seqb.common.mybatis.WrapperHandler;
import com.seqb.common.utils.RedisUtils;
import com.seqb.exception.BdException;
import com.seqb.manage.dict.dao.DictDao;
import com.seqb.manage.dict.domain.DictDO;
import com.seqb.manage.dict.service.DictService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;

/**
 * @author lilinshen
 * @title 请填写标题
 * @description 请填写相关描述
 * @date 2019/11/14
 */
@Service
public class DictServiceImpl implements DictService {
    @Autowired
    private DictDao dictDao;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public DictDO get(Long id) {
        return dictDao.selectById(id);
    }

    @Override
    public Page<DictDO> list(Map<String, Object> map) {
        if (null != map && null != map.get("pageNumber") && null != map.get("pageSize")) {
            PageHelper.startPage(Integer.valueOf(map.get("pageNumber").toString()), Integer.valueOf(map.get("pageSize").toString()));
        } else {
            PageHelper.startPage(1, Integer.MAX_VALUE);
        }
        QueryWrapper queryWrapper = WrapperHandler.genQueryWrapper(map, DictDO.class);
        return (Page<DictDO>) dictDao.selectList(queryWrapper);
    }

    @Override
    public int count(Map<String, Object> map) {
        QueryWrapper queryWrapper = WrapperHandler.genQueryWrapper(map, DictDO.class);
        return dictDao.selectCount(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo save(DictDO dict) {
        try {
            String name = dict.getName();
            String value = dict.getValue();
            String type = dict.getType();
            if (StringUtils.isEmpty(name) || StringUtils.isEmpty(value) || StringUtils.isEmpty(type)) {
                return ResultVo.error("参数不足！");
            }
            int insert = dictDao.insert(dict);
            if (insert <= 0) {
                throw new BdException("操作失败！");
            }
            return ResultVo.ok();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return ResultVo.error("操作失败！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo update(DictDO dict) {
        try {
            int update = 0;
            Long id = dict.getId();
            if (null == id) {
                return ResultVo.error("参数不足！");
            }
            DictDO existDO = dictDao.selectById(id);
            if (null == existDO) {
                return ResultVo.error("数据不存在！");
            }
            String clearField = dict.getClearField();
            if (StringUtils.isEmpty(clearField)) {
                update = dictDao.updateById(dict);
            } else {
                UpdateWrapper updateWrapper = WrapperHandler.genUpdateWrapper(dict);
                updateWrapper.eq("id", id);
                update = dictDao.update(dict, updateWrapper);
            }
            if (update <= 0) {
                throw new BdException("操作失败！");
            }
            return ResultVo.ok();
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return ResultVo.error("操作失败！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int remove(Long id) {
        return dictDao.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchRemove(Long[] ids) {
        return dictDao.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 同步字典表的数据到redis中
     */
    @Override
    public ResultVo syncDictCache() {
        try {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.orderByAsc("sort_number");
            List<DictDO> dictList = dictDao.selectList(queryWrapper);
            if (null != dictList && dictList.size() > 0) {
                Map<String, Object> dictMap = new HashMap<>(16);
                for (DictDO dict : dictList) {
                    String key = dict.getType();
                    List tempDictList = null;
                    if (dictMap.containsKey(key)) {
                        tempDictList = (List) dictMap.get(key);
                    } else {
                        tempDictList = new ArrayList();
                    }
                    tempDictList.add(dict);
                    dictMap.put(key, tempDictList);
                }
                if (!dictMap.isEmpty()) {
                    Set set = dictMap.keySet();
                    Iterator it = set.iterator();
                    while (it.hasNext()) {
                        String key = (String) it.next();
                        List value = (List) dictMap.get(key);
                        if (!redisUtils.set(RedisConfig.DICT_PREFIX + key, value)) {
                            return ResultVo.error("缓存服务器连接失败，请联系管理员！");
                        }
                    }
                }
            }
            return ResultVo.ok();
        } catch (Exception e) {
            return ResultVo.error();
        }
    }

    /**
     * 根据type获取redis中的缓存，支持redis宕机情况
     */
    @Override
    public List<DictDO> getDictCache(String type) {
        if (StringUtils.isEmpty(type)) {
            return null;
        }
        List<DictDO> list = null;
        try {
            Object result = redisUtils.get(RedisConfig.DICT_PREFIX + type);
            if (null == result) {
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("type", type);
                queryWrapper.orderByAsc("sort_number");
                list = dictDao.selectList(queryWrapper);
                redisUtils.set(RedisConfig.DICT_PREFIX + type, list);
            } else {
                list = JSON.parseArray(result.toString(), DictDO.class);
            }
        } catch (Exception e) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("type", type);
            list = dictDao.selectList(queryWrapper);
        }
        return list;
    }

    /**
     * 根据type或parentId获取redis中的缓存，支持redis宕机情况
     */
    @Override
    public List<DictDO> getDictList(String type, Long parentId) {
        if (StringUtils.isEmpty(type) && null == parentId) {
            return new ArrayList<>();
        }
        List<DictDO> list = new ArrayList<>();
        try {
            if (StringUtils.isNotEmpty(type)) {
                list = getDictCache(type);
            } else if (null != parentId) {
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("parent_id", parentId);
                queryWrapper.orderByAsc("sort_number");
                list = dictDao.selectList(queryWrapper);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

}
